﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Forest.Cat.Domain.Entities;
using Forest.Core.Caching;
using Forest.Core.Data;
using Forest.Cat.Domain.Shared;
using System.Text.RegularExpressions;

namespace Forest.Cat.Domain.Configuration
{

    public class LovService : ILovService
    {
        #region Field
        private const string LOV_ALL_KEY = "cat.lov.all";
        private readonly ICacheManager _cacheManager;
        private readonly IRepository<Lov> _lovRepository;
        #endregion

        #region Property
        private List<Lov> LovList
        {
            get
            {
                return _cacheManager.Get(LOV_ALL_KEY, () =>
                {
                    var list = _lovRepository.Table.ToList();
                    //加入面议项
                    list.Add(new Lov()
                    {
                        Id = ConstManager.Negotiable,
                        Name = "面议",
                        ParentId = Guid.Parse("00000000-0000-0000-0000-000000104000"),
                        Value = 104199,
                        SortOrder = 99
                    });

                    return list;
                });
            }
        }
        #endregion

        #region Ctor
        public LovService(ICacheManager cacheManager, IRepository<Lov> lovRepository)
        {
            _cacheManager = cacheManager;
            _lovRepository = lovRepository;
        }
        #endregion

        #region Method
        /// <summary>
        /// 获取所有列表
        /// </summary>
        /// <returns></returns>
        public List<Lov> GetAll()
        {
            return LovList;
        }

        /// <summary>
        /// 通过值获取对应名称
        /// </summary>
        /// <param name="value"></param>
        /// <returns></returns>
        public String GetLovName(int value)
        {
            var lov = LovList.FirstOrDefault(item => item.Value == value);
            if (lov != null)
            {
                return lov.Name;
            }
            else
            {
                return String.Empty;
            }
        }

        public IQueryable<Lov> GetLovList(LovType lovType)
        {
            var lovTypeValue = ((int)lovType).ToString();
            //格式化：例如 201000 格式化成 00000000-0000-0000-0000-000000201000 的形式
            var regex = new Regex(@"\d{" + lovTypeValue.Length + "}$");
            var parentId = Guid.Parse(regex.Replace(Guid.Empty.ToString(), lovTypeValue));
            return _lovRepository.Table.Where(item => item.ParentId.HasValue && item.ParentId.Value.Equals(parentId));
        }

        public Lov GetLovById(Guid guid)
        {
            return _lovRepository.Table.FirstOrDefault(i => i.Id.Equals(guid));
        }

        public IQueryable<Lov> GetLovByParentId(Guid guid)
        {
            var lov = from a in _lovRepository.Table
                      where a.ParentId == guid
                      orderby a.SortOrder
                      select a;

            return lov;
        }

        public IQueryable<Lov> GetLovByParentLabel(string label)
        {
            //var lov = from a in _lovRepository.Table
            //          where a.Label == label
            //          orderby a.SortOrder
            //          select a;

            //return lov;
            var lovId = _lovRepository.Table.Where(w => w.Label == label).Select(s => s.Id).FirstOrDefault();
            return _lovRepository.Table.Where(item => item.ParentId.HasValue && item.ParentId.Value == lovId);
        }

        #endregion

        #region Extend Methods
        #region 获取发布日期

        /// <summary>
        /// 获取发布日期
        /// </summary>
        /// <param name="postedDateLovValue"></param>
        /// <returns></returns>
        public DateTime? GetPostedDate(int postedDateLovValue)
        {
            var postedDateType = (PostedDateType)Enum.Parse(typeof(PostedDateType), postedDateLovValue.ToString());
            return GetPostedDate(postedDateType);
        }

        /// <summary>
        /// 获取发布日期
        /// </summary>
        /// <param name="postedDateType"></param>
        /// <returns></returns>
        public DateTime? GetPostedDate(PostedDateType postedDateType)
        {
            DateTime? tempDate = null;
            if (postedDateType != PostedDateType.All)
            {
                tempDate = DateTime.Now.Date;
                switch (postedDateType)
                {
                    case PostedDateType.OneDay:
                        tempDate = tempDate.Value.AddDays(-1);
                        break;
                    case PostedDateType.TwoDay:
                        tempDate = tempDate.Value.AddDays(-2);
                        break;
                    case PostedDateType.ThreeDay:
                        tempDate = tempDate.Value.AddDays(-3);
                        break;
                    case PostedDateType.OneWeek:
                        tempDate = tempDate.Value.AddDays(-7);
                        break;
                    case PostedDateType.HalfMonth:
                        tempDate = tempDate.Value.AddDays(-15);
                        break;
                    case PostedDateType.OneMonth:
                        tempDate = tempDate.Value.AddMonths(-1);
                        break;
                    case PostedDateType.OneAndHalfMonth:
                        tempDate = tempDate.Value.AddDays(-45);
                        break;
                    case PostedDateType.TwoMonth:
                        tempDate = tempDate.Value.AddMonths(-2);
                        break;
                    case PostedDateType.ThreeMonth:
                        tempDate = tempDate.Value.AddMonths(-3);
                        break;
                }
            }
            return tempDate;
        }
        #endregion

        #region 获取职位类别的子列表
        /// <summary>
        /// 获取职位类别的子列表
        /// </summary>
        /// <returns></returns>
        public IQueryable<Lov> GetSubJobCategoryList()
        {
            var resultList = from subItem in _lovRepository.Table
                             join item in GetLovList(LovType.JobCategory)
                             on subItem.ParentId equals item.Id
                             select subItem;
            return resultList;
        }
        #endregion

        /// <summary>
        /// 根据类型获取子列表
        /// </summary>
        /// <param name="type"></param>
        /// <returns></returns>
        public IQueryable<Lov> GetSubListByParentValue(LovType type)
        {
            var resultList = from subItem in _lovRepository.Table
                             join item in GetLovList(type)
                             on subItem.ParentId equals item.Id
                             select subItem;
            return resultList;
        }

        /// <summary>
        /// 获取上级对象
        /// </summary>
        /// <param name="value"></param>
        /// <returns></returns>
        public Lov GetParent(int value)
        {
            return (from parent in _lovRepository.Table
                    join child in
                        (from item in _lovRepository.Table where item.Value.HasValue && item.Value.Value == value select item)
                         on new { HasValue = true, Value = parent.Id } equals new { child.ParentId.HasValue, child.ParentId.Value }
                    select parent).FirstOrDefault();

        }

        #endregion
    }
}
